#pragma once

#include <map>
#include <mutex>
#include <set>
#include <string>
#include <vector>

#include "bondlib.h"

using namespace std;

class BondSpecialLabel;
class S_BONDLIB_EXPORT BondSpecialLabelMgr {
 public:
  static BondSpecialLabelMgr& instance();
  void remove(const std::string& combBondKey);
  void clear();
  void removeLabel(const std::string& combBondKey, const std::string& id);
  void addLabel(const std::string& combBondKey, const std::string& id,
                const std::string& tips, int order);
  std::string getLabelTips(const std::string& combBondKey,
                           const std::string& id);
  vector<std::string> getLabelIDs(const std::string& combBondKey);

 private:
  BondSpecialLabelMgr();
  virtual ~BondSpecialLabelMgr();
  BondSpecialLabel* add(const std::string& combBondKey);
  BondSpecialLabel* get(const std::string& combBondKey);

 private:
  std::mutex m_mutex;
  std::map<std::string, BondSpecialLabel*> combBondKey2Label_;
};

class S_BONDLIB_EXPORT SpecialLabel {
 public:
  enum { PropertyTrade = 1, PropertyBond, PropertyClause };
  SpecialLabel();
  virtual ~SpecialLabel();
  const std::string& id() const { return id_; }
  void setId(const std::string& id) { id_ = id; }
  const std::string& label() const { return label_; }
  void SetLabel(const std::string& label) { label_ = label; }
  const std::string& color() const { return color_; }
  void SetColor(const std::string& color) { color_ = color; }
  const std::string& comment() const { return comment_; }
  void SetComment(const std::string& comment) { comment_ = comment; }
  int property() const { return property_; }
  void SetProperty(int property) { property_ = property; }
  int Order() const { return order_; }
  void SetOrder(int order) { order_ = order; }
  bool operator<(const SpecialLabel& r) const;
  bool IsDefaultCanShow() const;

 private:
  int property_;
  std::string id_;
  std::string label_;
  std::string color_;
  std::string comment_;
  int order_;
};

class S_BONDLIB_EXPORT SpecialLabelMgr {
 public:
  static SpecialLabelMgr& instance();
  void add(const SpecialLabel& label);
  void remove(const std::string& id);
  const SpecialLabel& get(const std::string& id);
  std::vector<SpecialLabel> getAll();
  void clear();
 private:
  SpecialLabelMgr();
  virtual ~SpecialLabelMgr();

  std::mutex m_mutex;
  std::map<std::string, SpecialLabel> labels_;
};